package org.evolution.util.db;

import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.log4j.Logger;

public class SqlUtil {

    private static final Logger logger = Logger.getLogger(SqlUtil.class);

    public static final int TYPE_MSSQL_MS = 1;
    public static final int TYPE_MSSQL_JTDS = 2;
    public static final int TYPE_ORACLE = 3;
    public static final int TYPE_MYSQL = 4;
    public static final int TYPE_POSTGRESQL = 5;
    public static final int TYPE_SYBASE = 6;//添加对sybase数据库的支持
    public static final int TYPE_OTHERS = 100;

    private int _driverType = -1;
    private String driverTypeStr = "auto";
    private DataSource dataSource;

    public SqlUtil(int driverType) {
        this._driverType = driverType;
        infoDriverType();
    }

    public SqlUtil() {
    }

    public void setDriverTypeStr(String driverTypeStr) {
        this.driverTypeStr = driverTypeStr;
    }

    public int getDriverType() {
        if (_driverType == -1) {
            if ("mssql_ms".equals(driverTypeStr)) {
                this._driverType = TYPE_MSSQL_MS;
            } else if ("mssql_jtds".equals(driverTypeStr)) {
                this._driverType = TYPE_MSSQL_JTDS;
            } else if ("oracle".equals(driverTypeStr)) {
                this._driverType = TYPE_ORACLE;
            } else if ("mysql".equals(driverTypeStr)) {
                this._driverType = TYPE_MYSQL;
            } else if ("postgresql".equals(driverTypeStr)) {
                this._driverType = TYPE_POSTGRESQL;
            } else if("sybase".equals(driverTypeStr)){//如果当前使用的是sybase数据库，_driverType设置为sybase驱动类型
                this._driverType = TYPE_SYBASE;
            }else if ("others".equals(driverTypeStr)) {
                this._driverType = TYPE_OTHERS;
            } else if ("auto".equals(driverTypeStr)) {
                detectDriverType();
            }
            infoDriverType();
        }
        return _driverType;
    }

    private void detectDriverType() {
        Connection con = null;
        try {
            logger.info("自动探测数据库类型...");
            con = dataSource.getConnection();
            DatabaseMetaData meta = con.getMetaData();
            String dbName = meta.getDatabaseProductName().toLowerCase();
            String driverName = meta.getDriverName().toLowerCase();
            if (dbName.indexOf("microsoft") != -1) {
                // "Microsoft SQL Server"
                if (driverName.indexOf("jtds") != -1) {
                    // jTDS Type 4 JDBC Driver for
                    // MS SQL Server and Sybase
                    _driverType = TYPE_MSSQL_JTDS;
                }else {
                    // SQLServer
                    _driverType = TYPE_MSSQL_JTDS;
                }
            } else if (dbName.indexOf("oracle") != -1) {
                _driverType = TYPE_ORACLE;
            } else if (dbName.indexOf("mysql") != -1) {// MySQL
                // MySQL-AB JDBC Driver
                _driverType = TYPE_MYSQL;
            } else if (dbName.indexOf("postgresql") != -1) {// PostgreSql
                // PostgreSql JDBC Driver
                _driverType = TYPE_POSTGRESQL;
            } else if(dbName.indexOf("ase")!=-1){//如果自动探测到当前使用的是sybase数据库，_driverType设置为sybase驱动类型
                _driverType = TYPE_SYBASE;   
            } else {
                _driverType = TYPE_OTHERS;
            }
        } catch (Exception e) {
            _driverType = TYPE_OTHERS;
        } finally {
            close(con);
        }
    }

    private void infoDriverType() {
        switch (_driverType) {
        case TYPE_MSSQL_MS:
            logger.info("数据库驱动程序类型设置为：MS JDBC driver for SQL Server");
            break;
        case TYPE_MSSQL_JTDS:
            logger.info("数据库驱动程序类型设置为：jtds for SQL Server");
            break;
        case TYPE_ORACLE:
            logger.info("数据库驱动程序类型设置为：Oracle");
            break;
        case TYPE_POSTGRESQL:
            logger.info("数据库驱动程序类型设置为：PostgreSql");
            break;
        case TYPE_SYBASE://如果当前使用的是sybase数据库，日志记录驱动信息
            logger.info("数据库驱动程序类型设置为：sybase");
            break;
        case TYPE_OTHERS:
            logger.info("数据库驱动程序类型设置为：Others");
            break;
        }

    }

    /**
     * 获取结果集中的数据到&lt;Map&gt;List，不关闭结果集。
     */
    public List<Map<String, Object>> getResultSetIntoListMap(ResultSet rs)
            throws SQLException {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        ResultSetMetaData meta = rs.getMetaData();
        int count = meta.getColumnCount();
        String[] colNames = new String[count];
        int[] colTypes = new int[count];
        for (int i = 0; i < count; i++) {
            colNames[i] = meta.getColumnName(i + 1).toUpperCase();
            colTypes[i] = meta.getColumnType(i + 1);
        }
        while (rs.next()) {
            Map<String, Object> m = getRowDataIntoMap(rs, colNames, colTypes);
            list.add(m);
        }
        return list;
    }

    /**
     * 将结果集中的第一行数据装到一个Map中，空集返回空Map而不是null，不关闭结果集。
     */
    public Map<String, Object> getResultSetIntoMap(ResultSet rs)
            throws SQLException {
        if (rs.next()) {
            return getRowDataIntoMap(rs);
        } else {
            return new HashMap<String, Object>();
        }
    }

    /**
     * 将结果集中的数据装到一个List中，每行只取第一列，空集返回空List而不是null，
     * 不关闭结果集。
     */
    public List<Object> getResultSetIntoList(ResultSet rs) throws SQLException {
        List<Object> list = new ArrayList<Object>();
        while (rs.next()) {
            list.add(rs.getObject(1));
        }
        return list;
    }

    /**
     * 获取一行的数据
     */
    public Map<String, Object> getRowDataIntoMap(ResultSet rs,
            String[] colNames, int[] colTypes) throws SQLException {
        Map<String, Object> m = new HashMap<String, Object>();
        for (int i = 0; i < colNames.length; i++) {
            String colName = colNames[i].toUpperCase();
            m.put(colName, getObject(rs, i + 1, colTypes[i]));
        }
        return m;
    }

    /**
     * 获取单个值，参数colIndex是基于1的下标。
     */
    public Object getObject(ResultSet rs, int colIndex, int colType)
            throws SQLException {
        // 取时间字段的信息
        switch (colType) {
        case Types.TIME:
            return rs.getTime(colIndex);
        case Types.TIMESTAMP:
            return rs.getTimestamp(colIndex);
        }

        switch (getDriverType()) {
        case TYPE_MSSQL_MS:
            switch (colType) {
            case Types.LONGVARCHAR:// Text
                // MS SQL
                // SERVER的JDBC驱动读Text类型数据当数据为NULL时会出异常
                try {
                    return rs.getObject(colIndex);
                } catch (Exception e) {
                    return "";
                }
            default:
                return rs.getObject(colIndex);
            }
        case TYPE_MSSQL_JTDS:
            switch (colType) {
            // JTds把MSSQL Text类型数据当做CLOB
            case Types.CLOB:
                Clob c = rs.getClob(colIndex);
                if (c != null) {
                    String str = c.getSubString(1, (int) c.length());
                    return str;
                } else {
                    return "";
                }
            default:
                return rs.getObject(colIndex);
            }
        case TYPE_ORACLE:
            switch (colType) {
            case Types.CLOB:
                Clob c = rs.getClob(colIndex);
                if (c != null) {
                    String str = c.getSubString(1, (int) c.length());
                    return str;
                } else {
                    return "";
                }
                // oracle 的 date 类型就是 datetime 类型
            case Types.DATE:
                return rs.getTimestamp(colIndex);
            default:
                return rs.getObject(colIndex);
            }
        default:
            return rs.getObject(colIndex);
        }
    }

    /**
     * 获取一行的数据
     * 
     * @throws SQLException
     */
    public Map<String, Object> getRowDataIntoMap(ResultSet rs)
            throws SQLException {
        ResultSetMetaData meta = rs.getMetaData();
        int count = meta.getColumnCount();
        String[] colNames = new String[count];
        int[] colTypes = new int[count];
        for (int i = 0; i < count; i++) {
            colNames[i] = meta.getColumnName(i + 1).toUpperCase();
            colTypes[i] = meta.getColumnType(i + 1);
        }
        return getRowDataIntoMap(rs, colNames, colTypes);
    }

    public PreparedStatement preparePageMainQuery(Connection con,
            String mainSql, int currentPage, int rowsPerPage, boolean limited)
            throws SQLException {
        PreparedStatement ps = null;
        if (currentPage == 1 || limited) {
            ps = con.prepareStatement(mainSql);
            ps.setMaxRows(rowsPerPage);
        } else {
            ps = con.prepareStatement(mainSql,
                    ResultSet.TYPE_SCROLL_INSENSITIVE,
                    ResultSet.CONCUR_READ_ONLY);
            ps.setMaxRows(currentPage * rowsPerPage);
        }
        ps.setFetchSize(rowsPerPage);
        ps.setFetchDirection(ResultSet.FETCH_FORWARD);
        return ps;
    }

    public String[] getColNames(ResultSetMetaData rsmd) throws SQLException {
        int count = rsmd.getColumnCount();
        String[] colNames = new String[count];
        for (int i = 0; i < count; i++) {
            colNames[i] = rsmd.getColumnName(i + 1).toUpperCase();
        }
        return colNames;
    }

    public int[] getColTypes(ResultSetMetaData rsmd) throws SQLException {
        int count = rsmd.getColumnCount();
        int[] colTypes = new int[count];
        for (int i = 0; i < count; i++) {
            colTypes[i] = rsmd.getColumnType(i + 1);
        }
        return colTypes;
    }

    /**
     * 屏蔽底层数据库差异的函数，做字符串拼接。 注意：目前支持的数据库不使用自定义函数。 例子：
     * 
     * <pre>
     * SQL Server
     * funcStrcat(&quot;COLA&quot;,&quot;COLB&quot;) 结果： &quot;COLA + COLB&quot;
     * funcStrcat(&quot;COLA&quot;,&quot;'abc'&quot;) 结果： &quot;COLA + 'abc'&quot;
     * funcStrcat(&quot;COLA&quot;,&quot;?&quot;) 结果： &quot;COLA + ?&quot;
     * </pre>
     */
    public String funcStrcat(String str1, String str2) {
        switch (getDriverType()) {
        case TYPE_ORACLE:
            return "(" + str1 + " || " + str2 + ")";
        case TYPE_MSSQL_JTDS:
        case TYPE_MSSQL_MS:
            return "(" + str1 + " + " + str2 + ")";
        case TYPE_MYSQL:
            return "CONCAT(" + str1 + "," + str2 + ")";
        case TYPE_POSTGRESQL:
            return "(" + str1 + " || " + str2 + ")";
        case TYPE_SYBASE://sybase数据库的字符串连接方式
            return "(" + str1 + " || " + str2 + ")";
        default:
            return "FUNC_STRCAT(" + str1 + "," + str2 + ")";
        }
    }

    /**
     * 屏蔽底层数据库差异的函数，做与运算。 注意：目前支持的数据库不使用自定义函数。 例子：
     * 
     * <pre>
     * SQL Server
     * funcBitAND(&quot;COLA&quot;,&quot;COLB&quot;) 结果： &quot;COLA &amp; COLB&quot;
     * funcBitAND(&quot;COLA&quot;,&quot;123&quot;) 结果： &quot;COLA &amp; 123&quot;
     * funcBitAND(&quot;COLA&quot;,&quot;?&quot;) 结果： &quot;COLA &amp; ?&quot;
     * </pre>
     */
    public String funcBitAND(String num1, String num2) {
        switch (getDriverType()) {
        case TYPE_ORACLE:
            return "BITAND(" + num1 + "," + num2 + ")";
        case TYPE_MSSQL_JTDS:
        case TYPE_MSSQL_MS:
        case TYPE_MYSQL:
            return "(" + num1 + " & " + num1 + ")";
        case TYPE_POSTGRESQL:
            return "(" + num1 + " & " + num1 + ")";
        case TYPE_SYBASE://sybase数据库的与运算
            return "(" + num1 + " & " + num1 + ")";
        default:
            return "FUNC_BITAND(" + num1 + "," + num1 + ")";
        }
    }

    /**
     * 屏蔽底层数据库差异的函数，做或运算。 注意：Oracle需要使用自定义函数。 例子：
     * 
     * <pre>
     * SQL Server
     * funcBitOR(&quot;COLA&quot;,&quot;COLB&quot;) 结果： &quot;COLA | COLB&quot;
     * funcBitOR(&quot;COLA&quot;,&quot;123&quot;) 结果： &quot;COLA | 123&quot;
     * funcBitOR(&quot;COLA&quot;,&quot;?&quot;) 结果： &quot;COLA | ?&quot;
     * </pre>
     */
    public String funcBitOR(String num1, String num2) {
        switch (getDriverType()) {
        case TYPE_MSSQL_JTDS:
        case TYPE_MSSQL_MS:
        case TYPE_MYSQL:
            return "(" + num1 + " | " + num1 + ")";
        case TYPE_POSTGRESQL:
            return "(" + num1 + " | " + num1 + ")";
        case TYPE_SYBASE://sybase数据库的或运算
            return "(" + num1 + " | " + num1 + ")";
        default:
            return "FUNC_BITOR(" + num1 + "," + num1 + ")";
        }
    }

    /**
     * 屏蔽底层数据库差异的函数，获取从右数第x位的值，x从1开始。 注意：都需要数据库自定义函数。 例子：
     * 
     * <pre>
     * SQL Server
     * funcBitGet(&quot;COLA&quot;,&quot;COLB&quot;) 结果： &quot;dbo.FUNC_BITGET(COLA,COLB)&quot;
     * funcBitGet(&quot;COLA&quot;,&quot;2&quot;) 结果： &quot;dbo.FUNC_BITGET(COLA,2)&quot;
     * funcBitGet(&quot;COLA&quot;,&quot;?&quot;) 结果： &quot;dbo.FUNC_BITGET(COLA,?)&quot;
     * </pre>
     */
    public String funcBitGet(String num, String pos) {
        switch (getDriverType()) {
        case TYPE_MSSQL_JTDS:
        case TYPE_MSSQL_MS:
            return "dbo.FUNC_BITGET(" + num + "," + pos + ")";
        case TYPE_MYSQL:
        case TYPE_POSTGRESQL:
        case TYPE_SYBASE://sybase数据库使用FUNC_BITGET函数
        default:
            return "FUNC_BITGET(" + num + "," + pos + ")";
        }
    }

    /**
     * 屏蔽底层数据库差异的函数，获取子串，beginIndex从1开始。
     * 注意：目前支持的数据库不使用自定义函数。 例子：
     * 
     * <pre>
     * SQL Server
     * funcSubstring(&quot;COLA&quot;,&quot;1&quot;,&quot;5&quot;) 结果： &quot;SUBSTRING(COLA,1,5)&quot;
     * funcSubstring(&quot;COLA&quot;,&quot;?&quot;,&quot;?&quot;) 结果： &quot;SUBSTRING(COLA,?,?)&quot;
     * </pre>
     */
    public String funcSubstring(String str, String beginIndex, String length) {
        switch (getDriverType()) {
        case TYPE_ORACLE:
            return "SUBSTR(" + str + "," + beginIndex + "," + length + ")";
        case TYPE_MSSQL_JTDS:
        case TYPE_MSSQL_MS:
        case TYPE_MYSQL:
            return "SUBSTRING(" + str + "," + beginIndex + "," + length + ")";
        case TYPE_POSTGRESQL:
            return "SUBSTR(" + str + "," + beginIndex + "," + length + ")";
        case TYPE_SYBASE://sybase数据库使用SUBSTRING函数
            return "SUBSTRING(" + str + "," + beginIndex + "," + length + ")";
        default:
            return "FUNC_SUBSTRING(" + str + "," + beginIndex + "," + length
                    + ")";
        }
    }

    /**
     * 屏蔽底层数据库差异的函数，获取子串，beginIndex从1开始。
     * 注意：目前支持的数据库不使用自定义函数。 例子：
     * 
     * <pre>
     * SQL Server
     * funcSubstring(&quot;COLA&quot;,&quot;3&quot;) 结果： &quot;SUBSTRING(COLA,3)&quot;
     * funcSubstring(&quot;COLA&quot;,&quot;?&quot;) 结果： &quot;SUBSTRING(COLA,?)&quot;
     * </pre>
     */
    public String funcSubstring(String str, String beginIndex) {
        switch (getDriverType()) {
        case TYPE_ORACLE:
            return "SUBSTR(" + str + "," + beginIndex + ")";
        case TYPE_MSSQL_JTDS:
        case TYPE_MSSQL_MS:
        case TYPE_MYSQL:
            return "SUBSTRING(" + str + "," + beginIndex + ")";
        case TYPE_POSTGRESQL:
            return "SUBSTR(" + str + "," + beginIndex + ")";
        case TYPE_SYBASE://sybase数据库使用LEFT函数
            return "LEFT(" + str + "," + beginIndex + ")";
        default:
            return "FUNC_SUBSTRING(" + str + "," + beginIndex + ")";
        }
    }

    /**
     * 屏蔽底层数据库差异的函数，获取子串下标，beginIndex从1开始。
     * 注意：目前支持的数据库不使用自定义函数。另外，在sqlserver和mysql下
     * 生成的字符串fullStr和strToBeFind的位置会颠倒，因此这两个参数不能都是问号。
     * 例子：
     * 
     * <pre>
     * SQL Server
     * funcSubstring(&quot;COLA&quot;,&quot;abc&quot;,&quot;5&quot;) 结果： &quot;CHARINDEX(&quot;abc&quot;,COLA,5)&quot;
     * funcSubstring(&quot;COLA&quot;,&quot;?&quot;,&quot;5&quot;) 结果： &quot;CHARINDEX(?,COLA,5)&quot;
     * </pre>
     */
    public String funcIndexOf(String fullStr, String strToBeFind,
            String beginIndex) {
        switch (getDriverType()) {
        case TYPE_ORACLE:
            return "INSTR(" + fullStr + "," + strToBeFind + "," + beginIndex
                    + ")";
        case TYPE_MSSQL_JTDS:
        case TYPE_MSSQL_MS:
            return "CHARINDEX(" + strToBeFind + "," + fullStr + ","
                    + beginIndex + ")";
        case TYPE_MYSQL:
            return "LOCATE(" + strToBeFind + "," + fullStr + "," + beginIndex
                    + ")";
        case TYPE_POSTGRESQL:
            return "STRPOS( SUBSTR(" + fullStr + ","+beginIndex+" )," + strToBeFind
            + ")+("+beginIndex+"-1)";
        case TYPE_SYBASE://根据官方文档，CHARINDEX函数的两个参数顺序和POSTGRESQL的STRPOS函数的两个参数的顺序是相反的
            return "CHARINDEX( " + strToBeFind + "," 
            + "SUBSTRING(" + fullStr + "," + beginIndex + ")" + ")+(" + beginIndex + "-1)";
        default:
            return "FUNC_INDEXOF(" + fullStr + "," + strToBeFind + ","
                    + beginIndex + ")";
        }
    }

    /**
     * 屏蔽底层数据库差异的函数，获取子串下标，beginIndex从1开始。
     * 注意：目前支持的数据库不使用自定义函数。另外，仅在sqlserver下
     * 生成的字符串fullStr和strToBeFind的位置会颠倒，因此这两个参数不能都是问号。
     * 例子：
     * 
     * <pre>
     * SQL Server
     * funcSubstring(&quot;COLA&quot;,&quot;abc&quot;) 结果： &quot;CHARINDEX(&quot;abc&quot;,COLA)&quot;
     * funcSubstring(&quot;COLA&quot;,&quot;?&quot;) 结果： &quot;CHARINDEX(?,COLA)&quot;
     * </pre>
     */
    public String funcIndexOf(String fullStr, String strToBeFind) {
        switch (getDriverType()) {
        case TYPE_ORACLE:
        case TYPE_MYSQL:
            return "INSTR(" + fullStr + "," + strToBeFind + ")";
        case TYPE_MSSQL_JTDS:
        case TYPE_MSSQL_MS:
            return "CHARINDEX(" + strToBeFind + "," + fullStr + ")";
        case TYPE_POSTGRESQL:
            return "strpos(" + fullStr + "," + strToBeFind + ")";
        case TYPE_SYBASE:
            return "CHARINDEX(" + strToBeFind + "," + fullStr + ")";
        default:
            return "FUNC_INDEXOF(" + fullStr + "," + strToBeFind + ")";
        }
    }

    /**
     * 屏蔽底层数据库差异的函数，当fullStr为null时,用defaultStr来替换。
     * 注意：目前支持的数据库不使用自定义函数。 例子：
     * 
     * <pre>
     * SQL Server
     * funcSubstring(&quot;COLA&quot;,&quot;abc&quot;) 结果： &quot;ISNULL(&quot;abc&quot;,COLA)&quot;
     * funcSubstring(&quot;COLA&quot;,&quot;?&quot;) 结果： &quot;ISNULL(?,COLA)&quot;
     * </pre>
     */
    public String funcIsNull(String fullStr, String defaultStr) {
        switch (getDriverType()) {
        case TYPE_ORACLE:
            return "NVL(" + fullStr + "," + defaultStr + ")";
        case TYPE_MYSQL:
            return "IFNULL(" + fullStr + "," + defaultStr + ")";
        case TYPE_MSSQL_JTDS:
        case TYPE_MSSQL_MS:
            return "ISNULL(" + fullStr + "," + defaultStr + ")";
        case TYPE_POSTGRESQL:
            return "COALESCE(" + fullStr + "," + defaultStr + ")";
        case TYPE_SYBASE:
            return "ISNULL(" + fullStr + "," + defaultStr + ")";
        default:
            return "NVL(" + fullStr + "," + defaultStr + ")";
        }
    }

    public String getDriverTypeStr() {
        return driverTypeStr;
    }

    /**
     * 安全的关闭ResultSet，可以用返回值是否为null判断关闭过程中是否发生了错误。
     * 如果关闭过程发生了错误，这个方法会将关闭过程中的错误记录到日志文件中，
     * 并就返回错误对象，否则返回null，如果参数为null就直接返回null。
     */
    public static Throwable close(ResultSet rs) {
        if (rs == null) {
            return null;
        }
        try {
            rs.close();
            return null;
        } catch (Throwable e) {
            logger
                    .warn("关闭ResultSet出错：（" + e.getClass() + "）"
                            + e.getMessage());
            return e;
        }
    }

    /**
     * 安全的关闭Statement，可以用返回值是否为null判断关闭过程中是否发生了错误。
     * 如果关闭过程发生了错误，这个方法会将关闭过程中的错误记录到日志文件中，
     * 并返回错误对象；否则返回null。如果参数为null就直接返回null。
     */
    public static Throwable close(Statement stmt) {
        if (stmt == null) {
            return null;
        }
        try {
            stmt.close();
            return null;
        } catch (Throwable e) {
            logger
                    .warn("关闭Statement出错：（" + e.getClass() + "）"
                            + e.getMessage());
            return e;
        }
    }

    /**
     * 安全的关闭Connection，可以用返回值是否为null判断关闭过程中是否发生了错误。
     * 如果关闭过程发生了错误，这个方法会将关闭过程中的错误记录到日志文件中，
     * 并返回错误对象；否则返回null。如果参数为null就直接返回null。
     */
    public static Throwable close(Connection con) {
        if (con == null) {
            return null;
        }
        try {
            con.close();
            return null;
        } catch (Throwable e) {
            logger.warn("关闭Connection出错：（" + e.getClass() + "）"
                    + e.getMessage());
            return e;
        }
    }

    /**
     * 回滚事务，如果回滚发生了错误，这个方法会将错误记录到日志中，
     * 并返回错误对象；否则返回null。如果参数con为null就直接返回null。
     */
    public static Throwable rollback(Connection con) {
        if (con == null) {
            return null;
        }
        String hash = "";
        try {
            hash = "(" + Integer.toHexString(con.hashCode()) + ") ";
            logger.info(hash + "开始回滚事务。");
            con.rollback();
            logger.info(hash + "事务已回滚。");
            return null;
        } catch (Throwable e) {
            logger.fatal(hash + "事务回滚失败!", e);
            return e;
        }
    }

    /**
     * 屏蔽底层数据库差异的函数，得到判断字段非空的条件语句
     * 
     * 例子：
     * 
     * <pre>
     * condSqlIsNotNull(&quot;COLUMN1&quot;) 
     * Oracle - &quot;COLUMN1 IS NOT NULL&quot;
     * SqlServer,MySql - &quot;NOT IS NOT NULL AND COLUMN1 &lt;&gt; ''&quot;
     * </pre>
     */
    public String condIsNotNull(String tableColumn) {
        String sql = tableColumn + " IS NOT NULL";
        switch (getDriverType()) {
        case SqlUtil.TYPE_ORACLE:
            sql = tableColumn + " IS NOT NULL";
            break;
        case SqlUtil.TYPE_MSSQL_JTDS:
        case SqlUtil.TYPE_MSSQL_MS:
        case SqlUtil.TYPE_MYSQL:
            sql = tableColumn + " IS NOT NULL AND " + tableColumn + " <> ''";
            break;
        default:
        }
        return sql;
    }

    /**
     * 屏蔽底层数据库差异的函数，得到判断字段为空的条件语句
     * 
     * 例子：
     * 
     * <pre>
     * condSqlIsNull(&quot;COLUMN1&quot;) 
     * Oracle - &quot;COLUMN1 IS NULL&quot;
     * SqlServer,MySql - &quot;COLUMN1 IS NULL OR COLUMN1 = ''&quot;
     * </pre>
     */
    public String condIsNull(String tableColumn) {
        String sql = tableColumn + " IS NULL";
        switch (getDriverType()) {
        case SqlUtil.TYPE_ORACLE:
            sql = tableColumn + " IS NULL";
            break;
        case SqlUtil.TYPE_MSSQL_JTDS:
        case SqlUtil.TYPE_MSSQL_MS:
        case SqlUtil.TYPE_MYSQL:
            sql = "(" + tableColumn + " IS NOT NULL OR " + tableColumn
                    + " = '')";
            break;
        default:
        }
        return sql;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

}